"""
@Author  : 康帅
@Time    : 2021/1/12 16:16
@Function: eval exec
"""
# eval语法：eval(expression, globals=None, locals=None)
"""
它有三个参数，其中 expression 是⼀个字符串类型的表达式或代码对象，⽤于做运算；globals 与 locals 是可选参数，默认值是 None。
"""
x = 10
y = 20
print(eval('x+y'))

# 语法：exec(object[, globals[, locals]])
"""
在 Python2 中 exec 是个语句，⽽ Python3 将其改造成⼀个函数，就像 print ⼀样。exec() 与 eval() ⾼度相似，三个参数的意义和作⽤相近。

主要的区别是，exec() 的第⼀个参数不是表达式，⽽是代码块，这意味着两点：⼀是它不能做表达式求值 并返回出去，⼆是它可以执⾏复杂的代码逻辑，
相对⽽⾔功能更加强⼤，例如，当代码块中赋值了新的变 量时，该变量可能 在函数外的命名空间中存活下来。

可以看出，exec() 内外的命名空间是相通的，变量由此传递出去，⽽不像 eval() 函数，需要⼀个变量来接 收函数的执⾏结果
"""
print('c=x + y')  # c=x + y
print(exec('c=x + y'))  # None

"""
两个函数都很强⼤，它们将字符串内容当做有效的代码执⾏。这是⼀种字符串驱动的事件 ，意义重⼤。
然⽽，在实际使⽤过程中，存在很多微⼩的细节，此处就列出我所知道的⼏点吧。 

常⻅⽤途：将字符串转成相应的对象，例如 string 转成 list ，string 转成 dict，string 转 tuple 等等
"""
a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
print(eval(a))  # [[1,2], [3,4], [5,6], [7,8], [9,0]]
a = "{'name': 'Python猫', 'age': 18}"
print(eval(a))  # {'name': 'Python猫', 'age': 18}

# 与 eval 略有不同
a = "my_dict = {'name': 'Python猫', 'age': 18}"
exec(a)
print(my_dict)  # {'name': 'Python猫', 'age': 18}

"""
eval() 函数的返回值是其 expression 的执⾏结果，在某些情况下，它会是 None，例如当该表达式是 print() 语句，或者是列表的 append() 操作时，
这类操作的结果是 None，因此 eval() 的返回值也会是 None
"""
result = eval('[].append(2)')
print(result)  # None

"""
exec() 函数的返回值只会是 None，与执⾏语句的结果⽆关，所以，将 exec() 函数赋值出去，就没有任何必要。
所执⾏的语句中，如果包含 return 或 yield ，它们产⽣的值也⽆法在 exec 函数的外部起作⽤
"""
result = exec('1 + 1')
print(result)  # None

